<template>
  <!-- 工具栏 -->
  <div class="table-tool">
    <div class="tool-title">
      <div class="title-divider"></div>
      <span class="title-text">查询结果</span>
    </div>
    <div class="tool-right">
      <!-- PDF打印 -->
      <div v-if="tableTools" class="tool-btns">
        <div v-print="print">
          <el-button type="primary">导出</el-button>
        </div>
        <slot name="toolBtnPrint" />
      </div>
      <!-- 单行/多行文字展示 -->
      <div v-if="tableMultiLine" class="tool-btns">
        <el-radio-group
          v-model="multiLine"
          @change="multiLineChange"
          style="min-width: 0px; margin-right: 16px"
        >
          <el-radio value="single" size="large">单行</el-radio>
          <el-radio value="multi" size="large">多行</el-radio>
        </el-radio-group>
        <slot name="toolBtn" />
      </div>
      <!-- 排序 -->
      <div v-if="tableToolColumnsSort" style="margin-left: 10px">
        <el-dropdown placement="bottom-start" trigger="click">
          <span class="el-dropdown-link">
            排序<el-icon class="el-icon--right"><Finished /></el-icon>
          </span>
          <template #dropdown>
            <div class="drop-checkbox" style="width: 240px; padding: 10px">
              <div
                class="checkbox-top"
                style="
                  display: flex;
                  justify-content: space-between;
                  border-bottom: 1px dashed #ccc;
                "
              >
                <el-checkbox
                  v-model="checkAll"
                  :indeterminate="isIndeterminate"
                  @change="handleCheckAllChange"
                >
                  全部
                </el-checkbox>
                <p
                  style="
                    font-size: 14px;
                    color: #409eff;
                    line-height: 20px;
                    margin-top: 4px;
                    cursor: pointer;
                  "
                  @click="handleReset"
                >
                  恢复默认
                </p>
              </div>
              <div class="checkbox-list">
                <el-checkbox-group
                  v-model="checkedCities"
                  @change="handleCheckedCitiesChange"
                >
                  <div
                    ref="sortableContainer"
                    style="
                      height: 200px;
                      overflow-y: scroll;
                      overflow-x: hidden;
                    "
                  >
                    <el-checkbox
                      v-for="column in tableColumns"
                      :key="column.label"
                      :label="column.label"
                      :value="column.label"
                    >
                      <!-- 自定义内容 -->
                      <template #default>
                        <div
                          class="list-item"
                          style="
                            width: 200px;
                            display: flex;
                            justify-content: space-between;
                          "
                        >
                          <div class="item-left">
                            <el-icon class="el-icon--right"><Rank /></el-icon>
                            <span> {{ column.label }}</span>
                          </div>
                          <div class="item-right">
                            <el-tooltip content="左浮动" placement="bottom">
                              <el-icon
                                :class="[
                                  { 'item-left-icon1': column.fixed == true },
                                  { 'item-left-icon2': !column.fixed },
                                ]"
                                @click.stop="handleFixed('left', column)"
                                ><BottomLeft
                              /></el-icon>
                            </el-tooltip>
                            <el-tooltip content="右浮动" placement="bottom">
                              <el-icon
                                :class="[
                                  {
                                    'item-right-icon1': column.fixed == 'right',
                                  },
                                  {
                                    'item-right-icon2': column.fixed == 'null',
                                  },
                                ]"
                                @click.stop="handleFixed('right', column)"
                                ><BottomRight
                              /></el-icon>
                            </el-tooltip>
                          </div>
                        </div>
                      </template>
                    </el-checkbox>
                  </div>
                </el-checkbox-group>
              </div>
            </div>
          </template>
        </el-dropdown>
      </div>
    </div>
  </div>
  <!-- 顶部选项提示 -->
  <div v-if="columnType == 'selection'" class="select-top" style="color: #666">
    <p>已选择</p>
    <p style="margin: 0px 10px 0px 10px; color: rgb(102.2, 177.4, 255)">
      {{ selectionLength }}
    </p>
    <p>项</p>
  </div>
  <!-- table主体 -->
  <el-table
    ref="lcTableRef"
    id="printData"
    class="draggable"
    v-bind="$attrs"
    :data="tableData"
    :key="tableKey"
    :row-class-name="props.tableRowClassName"
    style="width: 100%"
    :summary-method="getSummaries"
    :show-overflow-tooltip="multiLine == 'single' ? true : false"
    :show-summary="showSummary"
    @selection-change="handleSelectionChange"
    @cell-mouse-enter="handleCellEnter"
    @cell-mouse-leave="handleCellLeave"
  >
    <el-table-column v-if="columnType" :type="columnType" width="55">
      <template v-if="columnType === 'expand'" #default="scope">
        <slot name="expand" :row="scope.row" :index="scope.$index" />
      </template>
    </el-table-column>
    <el-table-column
      v-for="column in tableColumns"
      v-bind="column"
      :key="column.prop"
    >
      <template v-if="column.slot" #default="scope">
        <slot :name="column.slotName" :row="scope.row" :index="scope.$index" />
      </template>
    </el-table-column>
  </el-table>
  <!-- 分页 -->
  <div v-if="pagination" class="pagination-wrapper">
    <el-pagination
      background
      layout="total, sizes, prev, pager, next, jumper"
      :page-sizes="[10, 20, 50]"
      :total="paginationData.total"
      v-model:page-size="paginationData.pageSize"
      v-model:currentPage="paginationData.currentPage"
      @current-change="handleCurrentChange"
      @size-change="handleSizeChange"
    />
  </div>
</template>

<script lang="ts" setup>
import { reactive, ref, h, onMounted, watch } from "vue";
import {
  ArrowDown,
  Finished,
  Rank,
  BottomLeft,
  BottomRight,
} from "@element-plus/icons-vue";
import Sortable from "sortablejs";

// 引入封装的axios请求
import { request } from "@/apis/request";

const props = withDefaults(
  defineProps<{
    tableData: Array<any>;
    requestConfig: any;
    columns: Array<any>;
    pagination: boolean;
    tableTools: boolean;
    tableMultiLine: string;
    tableToolColumnsSort: boolean;
    allowDrop: boolean;
    paginationConfig: any;
    columnType: string;
    showSummary: boolean;
    tableRowClassName: any;
  }>(),
  {
    tableData: () => [],
    columns: () => [],
    pagination: false,
    tableTools: false,
    tableMultiLine: "single",
    tableToolColumnsSort: false,
    allowDrop: false,
    paginationConfig: {
      total: 0,
      currentPage: 1,
      pageSize: 10,
    },
    columnType: "",
    requestConfig: {
      url: "",
      type: "",
      response: "",
    },
  },
);

watch(
  () => props.tableData,
  (newValue) => {
    tableData.value = newValue;
  },
);

watch(
  () => props.paginationConfig,
  (currentPage: any) => {
    paginationData.value.currentPage = currentPage.currentPage;
    paginationData.value.pageSize = currentPage.pageSize;
    paginationData.value.total = currentPage.total;
  },
  { deep: true },
);

const selectionLength = ref(0);
const multiLine = ref(props.tableMultiLine);
const tableColumns = ref(props.columns);

const print = {
  id: "printData",
  popTitle: "打印数据",
};

const emits = defineEmits<{
  (e: "page-change", currentPage: number): void;
  (e: "size-change", pageSize: number): void;
  (e: "selection-change", val: any): void;
}>();

const tableKey = ref(0);
const tableData = ref(props.tableData);
const paginationData = ref({
  currentPage: props.paginationConfig.currentPage,
  pageSize: props.paginationConfig.pageSize,
  total: props.paginationConfig.total,
});

const sortableContainer = ref(null);

const checkAll = ref(false);
const isIndeterminate = ref(true);
const checkedCities = ref();
const cities = ["Shanghai", "Beijing", "Guangzhou", "Shenzhen"];

onMounted(() => {
  // if (props.requestConfig.url) {
  //   getTableData();
  // }
  // if (props.allowDrop) {
  //   rowDrop();
  // }
  if (sortableContainer.value) {
    Sortable.create(sortableContainer.value as HTMLElement, {
      onEnd: ({ newIndex, oldIndex }) => {
        const currColumn = tableColumns.value.splice(oldIndex!, 1)[0];
        tableColumns.value.splice(newIndex!, 0, currColumn);
      },
    });
  }
});

const rowDrop = () => {
  // 要拖拽元素的父容器 tbody
  const tbody = document.querySelector(
    ".draggable .el-table__body-wrapper tbody",
  );
  if (tbody) {
    Sortable.create(tbody as HTMLElement, {
      //  可被拖拽的子元素
      draggable: ".draggable .el-table__row",
      onEnd({ newIndex, oldIndex }: any) {
        const currRow = tableData.value.splice(oldIndex, 1)[0];
        tableData.value.splice(newIndex, 0, currRow);
      },
    });
  }
};

const handleCurrentChange = (currentPage: number) => {
  paginationData.value.currentPage = currentPage;
  emits("page-change", currentPage);
};

const handleSizeChange = (pageSize: number) => {
  paginationData.value.pageSize = pageSize;
  emits("size-change", pageSize);
};

const handleSelectionChange = (val: any) => {
  selectionLength.value = val.length;
  emits("selection-change", val);
};
const getSummaries = (param: any) => {
  const { columns, data } = param;
  const sums: any[] = [];
  columns.forEach((column: any, index: any) => {
    if (index === 0) {
      sums[index] = h("div", { style: { textDecoration: "underline" } }, [
        "汇总：",
      ]);
      return;
    }
    const values = data.map((item: any) => Number(item[column.property]));
    if (!values.every((value: any) => Number.isNaN(value))) {
      sums[index] = `${values.reduce((prev: any, curr: any) => {
        const value = Number(curr);
        if (!Number.isNaN(value)) {
          return prev + curr;
        } else {
          return prev;
        }
      }, 0)}`;
    } else {
      sums[index] = "";
    }
  });

  return sums;
};
const handleCellEnter = (row: any, column: any, cell: any, event: any) => {
  row.isEdit = true;
};

const handleCellLeave = (row: any, column: any, cell: any, event: any) => {
  row.isEdit = false;
};

/**获取表格数据 */
const getTableData = () => {
  // 配置传入的 url地址 / 请求类型 / 传参
  let params = JSON.parse(props.requestConfig.response);
  request({
    url: props.requestConfig.url,
    method: props.requestConfig.type,
    params,
  }).then((res: any) => {
    tableData.value = res.data;
    paginationData.value.total = res.total;
  });
};

const multiLineChange = () => {
  tableKey.value++;
};

const handleTableLayout = (type: string) => {
  // tableData.value.
  if (type == "left") {
    if (tableColumns.value[0].fixed) {
      tableColumns.value[0].fixed = false;
    } else {
      tableColumns.value[0].fixed = true;
    }
  } else if (type == "right") {
    if (tableColumns.value[tableColumns.value.length - 1].fixed) {
      tableColumns.value[tableColumns.value.length - 1].fixed = false;
    } else {
      tableColumns.value[tableColumns.value.length - 1].fixed = "right";
    }
  }
  tableKey.value++;
};

const handleCheckAllChange = (val: any) => {
  let propList = tableColumns.value.map((item: any) => item.label);
  checkedCities.value = val ? propList : [];
  isIndeterminate.value = false;
};
const handleCheckedCitiesChange = (value: any[]) => {
  const checkedCount = value.length;
  checkAll.value = checkedCount === tableColumns.value.length;
  isIndeterminate.value =
    checkedCount > 0 && checkedCount < tableColumns.value.length;
};

const handleFixed = (type: string, column: any) => {
  if (type == "left") {
    if (column.fixed == "right" || column.fixed == "null") {
      column.fixed = true;
    } else if (column.fixed == true) {
      column.fixed = false;
    } else {
      column.fixed = true;
    }
  } else if (type == "right") {
    if (column.fixed == "right") {
      column.fixed = "null";
    } else {
      column.fixed = "right";
    }
  }
};

const handleReset = () => {
  isIndeterminate.value = true;
  tableColumns.value = props.columns;
  let propList = tableColumns.value.map((item: any) => item.label);
  checkedCities.value = propList;
};
</script>

<style lang="scss" scoped>
.table-tool {
  display: flex;
  justify-content: space-between;
  .tool-title {
    display: flex;
    align-items: center;
    .title-divider {
      width: 4px;
      height: 20px;
      border-radius: 2px;
      background-color: #409eff;
    }
    .title-text {
      color: #409eff;
      font-weight: 600;
      margin-left: 8px;
    }
  }
  .tool-btns {
    align-items: center;
    margin-right: 16px;
  }
  .tool-right {
    display: flex;
    // justify-content: center;
    align-items: center;
    .tool-btns {
      align-items: center;
    }
  }
}
.pagination-wrapper {
  display: flex;
  justify-content: flex-end;
  margin-top: 10px;
}
.select-top {
  width: 100%;
  height: 60px;
  margin-right: 20px;
  display: flex;
  align-items: center;
  background-color: rgba(247, 137, 137, 0.1);
  border-radius: 8px;
  padding-left: 20px;
  box-sizing: border-box;
}
:deep(.el-table__row) {
  height: 40px;
}
.el-checkbox__label .el-icon {
  color: rgba(96, 98, 102, 1);
}
.item-left-icon1 {
  color: #409eff !important;
}
.item-left-icon2 {
  color: rgba(96, 98, 102, 1) !important;
}
.item-right-icon1 {
  color: #409eff !important;
}
.item-right-icon2 {
  color: rgba(96, 98, 102, 1) !important;
}
</style>
